<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>JSDoc: Source: packages/layout/src/layout.vue</title>

    <script src="scripts/prettify/prettify.js"> </script>
    <script src="scripts/prettify/lang-css.js"> </script>
    <!--[if lt IE 9]>
      <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
    <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
    <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>

<body>

<div id="main">

    <h1 class="page-title">Source: packages/layout/src/layout.vue</h1>

    



    
    <section>
        <article>
            <pre class="prettyprint source linenums"><code>&lt;template>
  &lt;!-- 布局组件 -->
  &lt;div :class="`xdh-go-layout__menu ${customClass}`" :style="customStyle">
    &lt;slot :toggleLock="toggleLock" :changeLayout="changeLayout">
      &lt;ul>
        &lt;li @click="toggleLock()">
          &lt;el-tooltip :content="'固定布局切换'" placement="left" effect="light">
            &lt;i class="iconfont icon-pin icon" v-if="lock">&lt;/i>
            &lt;i class="iconfont icon-map-thumbtack icon" v-if="!lock">&lt;/i>
          &lt;/el-tooltip>
        &lt;/li>
        &lt;li>
          &lt;el-tooltip :content="'分层'" placement="left" effect="light" popper-class="invest-graph">
            &lt;i class="iconfont icon-Tandem icon">&lt;/i>
          &lt;/el-tooltip>
          &lt;ul>
            &lt;li @click="changeLayout('LayeredDigraphLayout', {direction:270})">
              &lt;i class="iconfont icon-arrow-up icon">&lt;/i>
            &lt;/li>
            &lt;li @click="changeLayout('LayeredDigraphLayout', {direction:90})">
              &lt;i class="iconfont icon-arrow-down icon">&lt;/i>
            &lt;/li>
            &lt;li @click="changeLayout('LayeredDigraphLayout', {direction:180})">
              &lt;i class="iconfont icon-arrow-left icon">&lt;/i>
            &lt;/li>
            &lt;li @click="changeLayout('LayeredDigraphLayout', {direction:0})">
              &lt;i class="iconfont icon-arrow-right icon">&lt;/i>
            &lt;/li>
          &lt;/ul>
        &lt;/li>
        &lt;!--力导向-->
        &lt;li @click="changeLayout('ForceDirectedLayout')">
          &lt;el-tooltip :content="'力导向'" placement="left" effect="light" popper-class="invest-graph">
            &lt;i class="iconfont icon-relation icon">&lt;/i>
          &lt;/el-tooltip>
        &lt;/li>
        &lt;!--网格-->
        &lt;li @click="changeLayout('GridLayout')">
          &lt;el-tooltip :content="'网格'" placement="left" effect="light" popper-class="invest-graph">
            &lt;i class="iconfont icon-nine-squares icon">&lt;/i>
          &lt;/el-tooltip>
        &lt;/li>
        &lt;!--圆形-->
        &lt;li @click="changeLayout('CircularLayout')">
          &lt;el-tooltip :content="'圆形'" placement="left" effect="light" popper-class="invest-graph">
            &lt;i class="iconfont icon-collaboration-system icon">&lt;/i>
          &lt;/el-tooltip>
        &lt;/li>
        &lt;!--树形-->
        &lt;li>
          &lt;el-tooltip :content="'树形'" placement="left" effect="light" popper-class="invest-graph">
            &lt;i class="iconfont icon-map-site icon">&lt;/i>
          &lt;/el-tooltip>
          &lt;ul class="bottom">
            &lt;li @click="changeLayout('TreeLayout', {angle:270})">
              &lt;i class="iconfont icon-arrow-up icon">&lt;/i>
            &lt;/li>
            &lt;li @click="changeLayout('TreeLayout', {angle:90})">
              &lt;i class="iconfont icon-arrow-down icon">&lt;/i>
            &lt;/li>
            &lt;li @click="changeLayout('TreeLayout', {angle:180})">
              &lt;i class="iconfont icon-arrow-left icon">&lt;/i>
            &lt;/li>
            &lt;li @click="changeLayout('TreeLayout', {angle:0})">
              &lt;i class="iconfont icon-arrow-right icon">&lt;/i>
            &lt;/li>
          &lt;/ul>
        &lt;/li>
      &lt;/ul>
    &lt;/slot>
  &lt;/div>
&lt;/template>
&lt;script>
import getLayout from '../../../utils/layout'
import go from 'gojs'
let $ = go.GraphObject.make
/**
   * XdhGoLayout功能组件
   * @module xdh-go-layout
   * @description 布局组件
   * @example
   *  &lt;xdh-go-layout
      :diagram="diagram"
      :lock.sync="lock"
      ref="layout"
      custom-class="my-layout"
    >&lt;/xdh-go-layout>
   */
/**
 * 插槽
 * @member slot
 * @property {String} [default] 默认插槽
 * @property {Function} [default.toggleLock] 设置lock开关
 * @property {Function} [default.changeLayout] 布局方法
 */
export default {
  name: 'XdhGoLayout',
  /**
   * 属性参数
   * @property {Object} diagram go.Diagram对象
   * @property {Boolean} lock 增删节点后其它节点是否重新布局
   * @property {String} customClass 自定义类名
   * @property {Object} customStyle 自定义style对象
   */
  props: {
    diagram: {
      type: Object,
      default() {
        return null
      }
    },
    lock: {
      type: Boolean,
      default: false
    },
    customClass: {
      type: String,
      default: ''
    },
    customStyle: {
      type: Object,
      default() {
        return {}
      }
    }
  },
  data() {
    return {
      currLayout: 'LayeredDigraphLayout',
      lockState: false,
      currOption: {}
    }
  },
  watch: {
    lock: {
      immediate: true,
      handler(val) {
        this.lockState = val
      }
    },
    lockState(val) {
      this.$emit('update:lock', val)
    },
    diagram: {
      handler(val) {
        if (val) {
          this.unbindEvents()
          setTimeout(() => {
            this.bindEvents()
          }, 100)
        }
      }
    }
  },
  computed: {},
  methods: {
    /**
     * @function
     * @name toggleLock
     * @description 设置lock开关
     */
    toggleLock() {
      this.lockState = !this.lockState
      if (this.lockState) {
        let layout = $(go.Layout)
        this.diagram.layout = layout
        this.diagram.layoutDiagram(true)
      } else {
        let type = this.currLayout
        let options = this.currOption
        if (type === 'GridLayout') {
          let nodeLength = this.diagram.model.nodeDataArray.length
          let num = Math.floor(Math.sqrt(nodeLength)) + 1
          options.wrappingColumn = num
        }
        let set = this.getAllNodesAndLinks()
        this.setNodesFixed(set, false)
        let layout = getLayout[type]($, go, options)
        layout.isOngoing = true
        this.diagram.layout = layout
        this.diagram.layoutDiagram(true)
      }
    },
    /**
     * @function
     * @name changeLayout
     * @param {String} type ForceDirectedLayout/GridLayout/CircularLayout/TreeLayout/LayeredDigraphLayout
     * @param {Object} options 布局类型参数
     * @description 设置布局
     * @example
     *   changeLayout('LayeredDigraphLayout', {direction:270})
     *   changeLayout('TreeLayout', {angle:270})
     *   changeLayout('CircularLayout')
     */
    changeLayout(type, options = {}) {
      /**
       * 切换布局时触发
       * @event on-search
       * @param {String} type 布局类型
       */
      this.$emit('on-change', type)
      this.currOption = options
      this.currLayout = type
      if (this.lockState) {
        // 设置简单布局，使position定位生效
        this.diagram.layout = $(go.Layout)
        this.diagram.layoutDiagram(true)
        if (this.diagram.selection.count !== 0) {
          let set = new go.Set()
          // 获得点集合的左上角坐标
          let posXmin, posYmin
          this.diagram.selection.each(N => {
            set.add(N)
            if (!posXmin || N.position.x &lt; posXmin) {
              posXmin = N.position.x
            }
            if (!posYmin || N.position.y &lt; posYmin) {
              posYmin = N.position.y
            }
          })
          let position = new go.Point(posXmin, posYmin)
          this.layoutNodes($, go, type, set, position, options)
        } else {
          let set = this.getAllNodesAndLinks()
          this.setNodesFixed(set, true)
          this.layoutNodes($, go, type, set, undefined, options)
        }
      } else {
        let set
        if (this.diagram.selection.count !== 0) {
          set = new go.Set()
          this.diagram.nodes.each(N => {
            N.isLayoutPositioned = false
          })
          this.diagram.selection.each(N => {
            set.add(N)
          })
        } else {
          set = this.getAllNodesAndLinks()
        }
        this.setNodesFixed(set, false)
        if (type === 'GridLayout') {
          let nodeLength = this.diagram.model.nodeDataArray.length
          let num = Math.floor(Math.sqrt(nodeLength)) + 1
          options.wrappingColumn = num
        }
        let layout = getLayout[type]($, go, options)
        layout.isOngoing = true
        this.diagram.layout = layout
        this.diagram.layoutDiagram(true)
      }
    },
    getAllNodesAndLinks() {
      let set = new go.Set()
      this.diagram.nodes.each(N => {
        set.add(N)
      })
      this.diagram.links.each(L => {
        set.add(L)
      })
      return set
    },
    layoutNodes($, go, type, nodes, position, options = {}) {
      if (type === 'GridLayout') {
        let nodeLength = this.diagram.model.nodeDataArray.length
        let num = Math.floor(Math.sqrt(nodeLength)) + 1
        options.wrappingColumn = num
      }
      let layout = getLayout[type]($, go, options)
      // 如果不设置isOngoing为false, 添加完的节点会自动按照diagram.layout布局，节点集布局会失效
      this.diagram.layout.isOngoing = false
      this.setNodesFixed(nodes, false)
      layout.doLayout(nodes)
      this.setNodesFixed(nodes, true)
      this.diagram.layout.isOngoing = true
      // 如果是力布局，会以原有位置为基础布局，因此不需要再设置偏移
      if (position &amp;&amp; type !== 'ForceDirectedLayout') {
        this.diagram.moveParts(nodes, position)
      }
    },
    setNodesFixed(nodes, isFixed = true) {
      nodes.each(N => {
        N.isLayoutPositioned = !isFixed
      })
    },
    layoutAfterAdd(nodes, links) {
      if (nodes &amp;&amp; nodes.length === 0) {
        return
      }
      let nodeMap = {}
      let type = 'data'
      if (nodes[0].diagram) {
        type = 'node'
      }
      nodes.forEach(d => {
        nodeMap[d.key] = d
      })
      let parent = null
      nodes.forEach(d => {
        let node
        if (type === 'node') {
          node = d
        } else {
          node = this.diagram.findNodeForData(d)
        }
        if (node) {
          node.findNodesConnected().each(N => {
            if (!nodeMap[N.key]) {
              parent = N
            }
          })
        }
      })
      if (!parent) {
        let node
        if (type === 'node') {
          node = nodes[0]
        } else {
          node = this.diagram.findNodeForData(nodes[0])
        }
        let connects = node.findNodesConnected()
        connects.each(N => {
          parent = N
        })
      }
      let set = new go.Set()
      let cNodes = parent.findTreeChildrenNodes()
      let cLinks = parent.findTreeChildrenLinks()
      let posXmin = parent.position.x
      let posYmin = parent.position.y
      set.add(parent)
      if (cNodes) {
        cNodes.each(N => {
          set.add(N)
          if (N.position.x !== 0 &amp;&amp; N.position.y !== 0) {
            if (!posXmin || N.position.x &lt; posXmin) {
              posXmin = N.position.x
            }
            if (!posYmin || N.position.y &lt; posYmin) {
              posYmin = N.position.y
            }
          }
        })
      }
      let position = new go.Point(posXmin, posYmin)
      nodes.forEach(d => {
        let node
        if (type === 'node') {
          node = d
        } else {
          node = this.diagram.findNodeForData(d)
        }
        node.position = position
        set.add(node)
      })
      if (links &amp;&amp; links.length !== 0) {
        links.forEach(l => {
          let link
          if (type === 'node') {
            link = l
          } else {
            link = this.diagram.findLinkForData(l)
          }
          set.add(link)
        })
      }
      if (cLinks) {
        cLinks.each(L => {
          set.add(L)
        })
      }
      this.layoutNodes($, go, this.currLayout, set, position, this.currOption)
    },
    bindEvents() {},
    unbindEvents() {}
  },
  created() {}
}
&lt;/script>
</code></pre>
        </article>
    </section>




</div>

<nav>
    <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-utils_directives_draggable.html">utils/directives/draggable</a></li><li><a href="module-utils_directives_resizable.html">utils/directives/resizable</a></li><li><a href="module-utils_events.html">utils/events</a></li><li><a href="module-utils_storage.html">utils/storage</a></li><li><a href="module-xdh-go.html">xdh-go</a></li><li><a href="module-xdh-go-circle-menu.html">xdh-go-circle-menu</a></li><li><a href="module-xdh-go-draft.html">xdh-go-draft</a></li><li><a href="module-xdh-go-html.html">xdh-go-html</a></li><li><a href="module-xdh-go-layout.html">xdh-go-layout</a></li><li><a href="module-xdh-go-overview.html">xdh-go-overview</a></li><li><a href="module-xdh-go-search.html">xdh-go-search</a></li><li><a href="module-xdh-go-select.html">xdh-go-select</a></li><li><a href="module-xdh-go-snapshot.html">xdh-go-snapshot</a></li><li><a href="module-xdh-go-tool.html">xdh-go-tool</a></li><li><a href="module-xdh-go-tooltiip.html">xdh-go-tooltiip</a></li><li><a href="module-xdh-go-view.html">xdh-go-view</a></li><li><a href="module-xdh-go-viewer.html">xdh-go-viewer</a></li></ul><h3>Classes</h3><ul><li><a href="module-utils_directives_draggable-Draggable.html">Draggable</a></li><li><a href="module-utils_directives_resizable-Resizable.html">Resizable</a></li><li><a href="module-utils_events-Events.html">Events</a></li></ul><h3>Events</h3><ul><li><a href="module-xdh-go-view.html#~event:item-click">item-click</a></li><li><a href="module-xdh-go-select.html#~event:on-change">on-change</a></li><li><a href="module-xdh-go-search.html#~event:on-error">on-error</a></li><li><a href="module-xdh-go-circle-menu.html#~event:on-item-click">on-item-click</a></li><li><a href="module-xdh-go.html#~event:on-load-data">on-load-data</a></li><li><a href="module-xdh-go.html#~event:on-ready">on-ready</a></li><li><a href="module-xdh-go-search.html#~event:on-search">on-search</a></li><li><a href="module-xdh-go-snapshot.html#~event:on-snap">on-snap</a></li></ul><h3>Global</h3><ul><li><a href="global.html#animationPool">animationPool</a></li><li><a href="global.html#bindToState">bindToState</a></li><li><a href="global.html#ease">ease</a></li><li><a href="global.html#easeInBack">easeInBack</a></li><li><a href="global.html#easeInBounce">easeInBounce</a></li><li><a href="global.html#easeInCirc">easeInCirc</a></li><li><a href="global.html#easeInCubic">easeInCubic</a></li><li><a href="global.html#easeInElastic">easeInElastic</a></li><li><a href="global.html#easeInExpo">easeInExpo</a></li><li><a href="global.html#easeInOutBack">easeInOutBack</a></li><li><a href="global.html#easeInOutBounce">easeInOutBounce</a></li><li><a href="global.html#easeInOutCubic">easeInOutCubic</a></li><li><a href="global.html#easeInOutQuad">easeInOutQuad</a></li><li><a href="global.html#easeInOutQuart">easeInOutQuart</a></li><li><a href="global.html#easeInOutQuint">easeInOutQuint</a></li><li><a href="global.html#easeInOutSine">easeInOutSine</a></li><li><a href="global.html#easeInQuad">easeInQuad</a></li><li><a href="global.html#easeInQuart">easeInQuart</a></li><li><a href="global.html#easeInQuint">easeInQuint</a></li><li><a href="global.html#easeInSine">easeInSine</a></li><li><a href="global.html#easeOutBack">easeOutBack</a></li><li><a href="global.html#easeOutBounce">easeOutBounce</a></li><li><a href="global.html#easeOutCirc">easeOutCirc</a></li><li><a href="global.html#easeOutCubic">easeOutCubic</a></li><li><a href="global.html#easeOutElastic">easeOutElastic</a></li><li><a href="global.html#easeOutExpo">easeOutExpo</a></li><li><a href="global.html#easeOutQuad">easeOutQuad</a></li><li><a href="global.html#easeOutQuart">easeOutQuart</a></li><li><a href="global.html#easeOutQuint">easeOutQuint</a></li><li><a href="global.html#easeOutSine">easeOutSine</a></li><li><a href="global.html#extendOption">extendOption</a></li><li><a href="global.html#genOption">genOption</a></li><li><a href="global.html#getHandler">getHandler</a></li><li><a href="global.html#handleEvents">handleEvents</a></li><li><a href="global.html#handleParts">handleParts</a></li><li><a href="global.html#horPanel%25E6%25B0%25B4%25E5%25B9%25B3%25E5%25B8%2583%25E5%25B1%2580">horPanel 水平布局</a></li><li><a href="global.html#makePort">makePort</a></li><li><a href="global.html#node%25E8%258A%2582%25E7%2582%25B9%25E5%25AE%259A%25E4%25B9%2589">node 节点定义</a></li><li><a href="global.html#removeGray">removeGray</a></li><li><a href="global.html#setGray">setGray</a></li><li><a href="global.html#shapeParamsBinding">shapeParamsBinding</a></li><li><a href="global.html#spotPanelspot%25E5%25B8%2583%25E5%25B1%2580">spotPanel spot布局</a></li><li><a href="global.html#verPanel%25E5%259E%2582%25E7%259B%25B4%25E5%25B8%2583%25E5%25B1%2580">verPanel 垂直布局</a></li></ul>
</nav>

<br class="clear">

<footer>
    Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 3.6.3</a> on Tue Nov 05 2019 16:15:35 GMT+0800 (GMT+08:00)
</footer>

<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>
